"use client";

import {
  createContext,
  useContext,
  useState,
  useEffect,
  type ReactNode,
} from "react";
import { message } from "antd";
import type {
  Host,
  Department,
  Project,
  Module,
  HostsBlock,
  Log,
  HostsFilter,
  HostTypeDefinition,
} from "../types";
import {
  fetchHosts,
  fetchDepartments,
  fetchProjects,
  fetchModules,
  fetchHostsBlocks,
  fetchLogs,
  fetchHostTypes,
  createHostsBlock,
  updateHostsBlock as updateHostsBlockApi,
  deleteHostsBlock as deleteHostsBlockApi,
  createProject,
  updateProject as updateProjectApi,
  deleteProject as deleteProjectApi,
  createModule,
  updateModule as updateModuleApi,
  deleteModule as deleteModuleApi,
  createDepartment,
  updateDepartment as updateDepartmentApi,
  deleteDepartment as deleteDepartmentApi,
} from "../services/api";

interface HostsContextType {
  hosts: Host[];
  departments: Department[];
  projects: Project[];
  modules: Module[];
  hostsBlocks: HostsBlock[];
  logs: Log[];
  hostTypes: HostTypeDefinition[];
  loading: boolean;
  filter: HostsFilter;
  setFilter: (filter: HostsFilter) => void;
  addHostsBlock: (
    hostsBlock: Omit<HostsBlock, "id" | "createdAt" | "updatedAt" | "createdBy">
  ) => void;
  updateHostsBlock: (id: string, hostsBlock: Partial<HostsBlock>) => void;
  deleteHostsBlock: (id: string) => void;
  addProject: (project: Omit<Project, "id" | "createdAt">) => void;
  updateProject: (id: string, project: Partial<Project>) => void;
  deleteProject: (id: string) => void;
  addModule: (module: Omit<Module, "id" | "createdAt">) => void;
  updateModule: (id: string, module: Partial<Module>) => void;
  deleteModule: (id: string) => void;
  addDepartment: (department: Omit<Department, "id">) => void;
  updateDepartment: (id: string, department: Partial<Department>) => void;
  deleteDepartment: (id: string) => void;
  addHostType: (hostType: Omit<HostTypeDefinition, "id" | "createdAt">) => void;
  updateHostType: (id: string, hostType: Partial<HostTypeDefinition>) => void;
  deleteHostType: (id: string) => void;
  refreshData: () => Promise<void>;
}

const HostsContext = createContext<HostsContextType | undefined>(undefined);

export const useHosts = () => {
  const context = useContext(HostsContext);
  if (!context) {
    throw new Error("useHosts must be used within a HostsProvider");
  }
  return context;
};

export const HostsProvider = ({ children }: { children: ReactNode }) => {
  const [hosts, setHosts] = useState<Host[]>([]);
  const [departments, setDepartments] = useState<Department[]>([]);
  const [projects, setProjects] = useState<Project[]>([]);
  const [modules, setModules] = useState<Module[]>([]);
  const [hostsBlocks, setHostsBlocks] = useState<HostsBlock[]>([]);
  const [logs, setLogs] = useState<Log[]>([]);
  const [hostTypes, setHostTypes] = useState<HostTypeDefinition[]>([]);
  const [loading, setLoading] = useState(true);
  const [filter, setFilter] = useState<HostsFilter>({
    search: "",
    department: undefined,
    project: undefined,
    environment: undefined,
    type: undefined,
  });

  const refreshData = async () => {
    setLoading(true);
    try {
      const [
        hostsData,
        departmentsData,
        projectsData,
        modulesData,
        hostsBlocksData,
        logsData,
        hostTypesData,
      ] = await Promise.all([
        fetchHosts(),
        fetchDepartments(),
        fetchProjects(),
        fetchModules(),
        fetchHostsBlocks(),
        fetchLogs(),
        fetchHostTypes(),
      ]);

      setHosts(hostsData);
      setDepartments(departmentsData);
      setProjects(projectsData);
      setModules(modulesData);
      setHostsBlocks(hostsBlocksData);
      setLogs(logsData);
      setHostTypes(hostTypesData);
    } catch (error) {
      console.error("Failed to fetch data:", error);
      message.error("获取数据失败，请稍后重试");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    refreshData();
  }, []);

  const addHostsBlock = async (
    hostsBlock: Omit<HostsBlock, "id" | "createdAt" | "updatedAt" | "createdBy">
  ) => {
    try {
      const newHostsBlock = await createHostsBlock(hostsBlock);

      setHostsBlocks((prev) => [...prev, newHostsBlock]);
      message.success("主机配置添加成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to add hosts block:", error);
      message.error("添加主机配置失败，请稍后重试");
    }
  };

  const updateHostsBlock = async (
    id: string,
    hostsBlockUpdate: Partial<HostsBlock>
  ) => {
    try {
      await updateHostsBlockApi(id, hostsBlockUpdate);

      setHostsBlocks((prev) =>
        prev.map((block) =>
          block.id === id
            ? {
                ...block,
                ...hostsBlockUpdate,
                updatedAt: new Date().toISOString(),
              }
            : block
        )
      );

      message.success("主机配置更新成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to update hosts block:", error);
      message.error("更新主机配置失败，请稍后重试");
    }
  };

  const deleteHostsBlock = async (id: string) => {
    try {
      await deleteHostsBlockApi(id);

      setHostsBlocks((prev) => prev.filter((block) => block.id !== id));
      message.success("主机配置删除成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to delete hosts block:", error);
      message.error("删除主机配置失败，请稍后重试");
    }
  };

  const addProject = async (project: Omit<Project, "id" | "createdAt">) => {
    try {
      const newProject = await createProject(project);

      setProjects((prev) => [...prev, newProject]);
      message.success("项目添加成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to add project:", error);
      message.error("添加项目失败，请稍后重试");
    }
  };

  const updateProject = async (id: string, projectUpdate: Partial<Project>) => {
    try {
      await updateProjectApi(id, projectUpdate);

      setProjects((prev) =>
        prev.map((project) =>
          project.id === id
            ? {
                ...project,
                ...projectUpdate,
              }
            : project
        )
      );

      message.success("项目更新成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to update project:", error);
      message.error("更新项目失败，请稍后重试");
    }
  };

  const deleteProject = async (id: string) => {
    try {
      await deleteProjectApi(id);

      setProjects((prev) => prev.filter((project) => project.id !== id));
      message.success("项目删除成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to delete project:", error);
      message.error("删除项目失败，请稍后重试");
    }
  };

  const addModule = async (module: Omit<Module, "id" | "createdAt">) => {
    try {
      const newModule = await createModule(module);

      setModules((prev) => [...prev, newModule]);
      message.success("模块添加成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to add module:", error);
      message.error("添加模块失败，请稍后重试");
    }
  };

  const updateModule = async (id: string, moduleUpdate: Partial<Module>) => {
    try {
      await updateModuleApi(id, moduleUpdate);

      setModules((prev) =>
        prev.map((module) =>
          module.id === id
            ? {
                ...module,
                ...moduleUpdate,
              }
            : module
        )
      );

      message.success("模块更新成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to update module:", error);
      message.error("更新模块失败，请稍后重试");
    }
  };

  const deleteModule = async (id: string) => {
    try {
      await deleteModuleApi(id);

      setModules((prev) => prev.filter((module) => module.id !== id));
      message.success("模块删除成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to delete module:", error);
      message.error("删除模块失败，请稍后重试");
    }
  };

  const addDepartment = async (department: Omit<Department, "id">) => {
    try {
      const newDepartment = await createDepartment(department);

      setDepartments((prev) => [...prev, newDepartment]);
      message.success("部门添加成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to add department:", error);
      message.error("添加部门失败，请稍后重试");
    }
  };

  const updateDepartment = async (
    id: string,
    departmentUpdate: Partial<Department>
  ) => {
    try {
      await updateDepartmentApi(id, departmentUpdate);

      setDepartments((prev) =>
        prev.map((department) =>
          department.id === id
            ? {
                ...department,
                ...departmentUpdate,
              }
            : department
        )
      );

      message.success("部门更新成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to update department:", error);
      message.error("更新部门失败，请稍后重试");
    }
  };

  const deleteDepartment = async (id: string) => {
    try {
      await deleteDepartmentApi(id);

      setDepartments((prev) =>
        prev.filter((department) => department.id !== id)
      );
      message.success("部门删除成功");
      // 刷新日志
      await refreshData();
    } catch (error) {
      console.error("Failed to delete department:", error);
      message.error("删除部门失败，请稍后重试");
    }
  };

  // Host Type CRUD operations
  const addHostType = (
    hostType: Omit<HostTypeDefinition, "id" | "createdAt">
  ) => {
    const newHostType: HostTypeDefinition = {
      ...hostType,
      id: Date.now().toString(),
      createdAt: new Date().toISOString(),
    };

    setHostTypes((prev) => [...prev, newHostType]);

    // Add log
    const newLog: Log = {
      id: Date.now().toString(),
      action: "create",
      targetType: "hostType",
      targetId: newHostType.id,
      targetName: newHostType.name,
      userId: "当前用户",
      userName: "当前用户",
      timestamp: new Date().toISOString(),
      details: `创建了主机类型 "${newHostType.name}"`,
    };

    setLogs((prev) => [newLog, ...prev]);

    message.success("主机类型添加成功");
  };

  const updateHostType = (
    id: string,
    hostTypeUpdate: Partial<HostTypeDefinition>
  ) => {
    setHostTypes((prev) =>
      prev.map((type) =>
        type.id === id
          ? {
              ...type,
              ...hostTypeUpdate,
            }
          : type
      )
    );

    // Add log
    const hostType = hostTypes.find((t) => t.id === id);
    if (hostType) {
      const newLog: Log = {
        id: Date.now().toString(),
        action: "update",
        targetType: "hostType",
        targetId: id,
        targetName: hostType.name,
        userId: "当前用户",
        userName: "当前用户",
        timestamp: new Date().toISOString(),
        details: `更新了主机类型 "${hostType.name}"`,
      };

      setLogs((prev) => [newLog, ...prev]);
    }

    message.success("主机类型更新成功");
  };

  const deleteHostType = (id: string) => {
    // Get the host type before deleting for the log
    const hostType = hostTypes.find((t) => t.id === id);

    // Check if there are hosts using this type
    const hostsUsingType = hosts.filter((h) => h.type === hostType?.code);
    if (hostsUsingType.length > 0) {
      message.error("无法删除主机类型，请先删除使用该类型的所有主机");
      return;
    }

    setHostTypes((prev) => prev.filter((type) => type.id !== id));

    // Add log
    if (hostType) {
      const newLog: Log = {
        id: Date.now().toString(),
        action: "delete",
        targetType: "hostType",
        targetId: id,
        targetName: hostType.name,
        userId: "当前用户",
        userName: "当前用户",
        timestamp: new Date().toISOString(),
        details: `删除了主机类型 "${hostType.name}"`,
      };

      setLogs((prev) => [newLog, ...prev]);
    }

    message.success("主机类型删除成功");
  };

  return (
    <HostsContext.Provider
      value={{
        hosts,
        departments,
        projects,
        modules,
        hostsBlocks,
        logs,
        hostTypes,
        loading,
        filter,
        setFilter,
        addHostsBlock,
        updateHostsBlock,
        deleteHostsBlock,
        addProject,
        updateProject,
        deleteProject,
        addModule,
        updateModule,
        deleteModule,
        addDepartment,
        updateDepartment,
        deleteDepartment,
        addHostType,
        updateHostType,
        deleteHostType,
        refreshData,
      }}
    >
      {children}
    </HostsContext.Provider>
  );
};
